package cn.jasonone.jame.model;

import cn.jasonone.jame.basic.Collision;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import lombok.Data;
import sun.rmi.transport.DGCImpl_Skel;

import java.awt.geom.Rectangle2D;
import java.util.Objects;

/**
 * 区域类
 *
 * @author Jason
 */
@Data
public class Rect implements Collision {
    /**
     * 坐标信息
     */
    private Point point;
    /**
     * 大小信息
     */
    private Dimension size;

    public Rect() {
        this(new Point(), new Dimension());
    }

    public Rect(Point point) {
        this(point, new Dimension());
    }

    public Rect(Dimension dimension) {
        this(new Point(), new Dimension());
    }


    public Rect(Point point, Dimension dimension) {
        this.setPoint(point);
        this.setSize(dimension);
    }

    public Rect(double x, double y, double width, double height) {
        this();
        this.setRect(x, y, width, height);
    }

    /**
     * 移动指定偏移量
     *
     * @param offsetX 横坐标偏移量
     * @param offsetY 纵坐标偏移量
     */
    public void move(double offsetX, double offsetY) {
        this.point.move(offsetX, offsetY);
    }

    /**
     * 移动到指定位置
     *
     * @param x 横坐标
     * @param y 纵坐标
     */
    public void moveTo(double x, double y) {
        this.point.moveTo(x, y);
    }

    public double getX() {
        return point.getX();
    }

    public DoubleProperty xProperty() {
        return point.xProperty();
    }

    public void setX(double x) {
        this.point.setX(x);
    }

    public double getY() {
        return this.point.getY();
    }

    public DoubleProperty yProperty() {
        return this.point.yProperty();
    }

    public void setY(double y) {
        this.point.setY(y);
    }

    public double getWidth() {
        return this.size.getWidth();
    }

    public DoubleProperty widthProperty() {
        return this.size.widthProperty();
    }

    public void setWidth(double width) {
        this.size.setWidth(width);
    }

    public double getHeight() {
        return this.size.getHeight();
    }

    public DoubleProperty heightProperty() {
        return this.size.heightProperty();
    }

    public void setHeight(double height) {
        this.size.setHeight(height);
    }

    @Override
    public boolean isContains(double x, double y) {
        Rectangle2D r = new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
        if (r.contains(x, y)) {
            return true;
        }
        return false;
    }

    @Override
    public boolean isContains(Rect rect) {
        Rectangle2D r = new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
        if (r.contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight())) {
            return true;
        }
        return false;
    }

    @Override
    public boolean isCollision(Rect rect) {
        Rectangle2D r = new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
        if (r.intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight())) {
            return true;
        }
        return false;
    }

    /**
     * 绑定区域
     *
     * @param rect 区域
     */
    public void bindRect(Rect rect) {
        this.getSize().bindDimension(rect.getSize());
        this.getPoint().bindPoint(rect.getPoint());
    }

    /**
     * 解绑指定区域
     *
     * @param rect 区域
     */
    public void unbindRect(Rect rect) {
        this.getSize().unbindDimension(rect.getSize());
        this.getPoint().unbindPoint(rect.getPoint());
    }

    /**
     * 设置区域位置及尺寸
     *
     * @param rect 区域
     */
    public void setRect(Rect rect) {
        this.setRect(rect.getPoint(), rect.getSize());
    }

    /**
     * 置区域位置及尺寸
     *
     * @param point 坐标点
     * @param size  尺寸
     */
    public void setRect(Point point, Dimension size) {
        this.setRect(point.getX(), point.getY(), size.getWidth(), size.getHeight());
    }

    /**
     * 置区域位置及尺寸
     *
     * @param x      横坐标
     * @param y      纵坐标
     * @param width  宽度
     * @param height 高度
     */
    public void setRect(double x, double y, double width, double height) {
        this.getPoint().moveTo(x, y);
        this.getSize().setDimension(width, height);
    }

    /**
     * 设置区域的尺寸
     *
     * @param size 尺寸对象
     */
    public void setSize(Dimension size) {
        Objects.requireNonNull(size, "尺寸不能为null");
        if (this.size == null) {
            this.size = size;
        }
        this.getSize().setDimension(size);
    }

    /**
     * 设置区域的尺寸
     *
     * @param width  宽度
     * @param height 高度
     */
    public void setSize(double width, double height) {
        this.getSize().setDimension(width, height);
    }
}
